import newArrayProto from "./array";
import Dep from "./dep";

class Observer {
    constructor(data) {
        Object.defineProperty(data,'__ob__', {
            value: this,
            enumerable: false
        })
        // data.__ob__ = this;
        if (Array.isArray(data)) {
            data.__proto__ = newArrayProto
            this.observeArray(data)
        }else {
            this.walk(data)
        }
    }

    walk(data) {
       Object.keys(data).forEach(key => {
        defineReactive(data, key, data[key])
       }) 
    }
    observeArray(data) {
        data.forEach(item => observe(item))
    }
}
export function defineReactive(target, key, value) {
    observe(value)
    let dep = new Dep();
    Object.defineProperty(target, key, {
        get() {
            if (Dep.target) {
                dep.depend();
            }
            return value;
        },
        set(newValue) {
            if(newValue === value) return;
            observe(newValue)
            value = newValue
            dep.notify();
        }
    })
}
export function observe(data) {

    if(typeof data !== 'object' || data == null) {
        return;
    }
    // 判断是否被劫持过的数据
    if (data.__ob__ instanceof Observer) {
        return data.__ob__;
    }
    return new Observer(data)
} 